package partitions;

import hips.Image;
import hips.PixelValue;
import hips.gui.ComponentLocation;
import hips.gui.NoMemoryFrame;
import hips.gui.WaitingFrame;
import hips.gui.parameters.ParameterFrame;
import hips.gui.parameters.ParameterListener;
import ij.ImageListener;
import ij.ImagePlus;
import java.util.LinkedList;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout;
import javax.swing.LayoutStyle.ComponentPlacement;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JRadioButton;
import java.awt.Font;

@SuppressWarnings("rawtypes")
public class MainFrame extends javax.swing.JFrame implements ParameterListener {
	private static final long serialVersionUID = 1L;

	private Image img;
	private javax.swing.JButton create;
	private javax.swing.JButton create1;
	private javax.swing.JLabel jLabel1;

	public javax.swing.JTabbedPane tabs;
	public LinkedList<Listener> listenerList;
	public ParameterFrame parameters;
	public int previousIterations;
	public Image outputImage;
	public JRadioButton allSlices;

	public MainFrame(Image img) {
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		addWindowListener(new WindowListener() {
			public void windowClosing(WindowEvent e) {
				if (e.getComponent() == MainFrame.this) {
					removeWindowListener(this);
					myDispose();
				}
			}

			public void windowClosed(WindowEvent e) {
			}

			public void windowActivated(WindowEvent e) {
			}

			public void windowOpened(WindowEvent e) {
			}

			public void windowIconified(WindowEvent e) {
			}

			public void windowDeiconified(WindowEvent e) {
			}

			public void windowDeactivated(WindowEvent e) {
			}
		});

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception ex) {
		}

		initComponents();
		WaitingFrame wait = new WaitingFrame();
		wait.setVisible(true);

		parameters = new ParameterFrame(img);
		parameters.addParameterListener(this);

		listenerList = new LinkedList<Listener>();

		ComponentLocation.setLocationCenter(0.25f, 0.5f, this);

		this.img = img;

		ImagePlus.addImageListener(new ImageListener() {
			public void imageUpdated(ImagePlus arg0) {
			}

			public void imageOpened(ImagePlus arg0) {
			}

			public void imageClosed(ImagePlus arg0) {
				if (arg0 == MainFrame.this.img.getImagePlus()) {
					MainFrame.this.myDispose();
					ImagePlus.removeImageListener(this);
				}
			}
		});

		wait.dispose();
		tabs.setTitleAt(0, "Empty");
		setVisible(true);
	}

	private void initComponents() {
		setBounds(100, 100, 490, 476);
		create = new javax.swing.JButton();
		tabs = new javax.swing.JTabbedPane();
		jLabel1 = new javax.swing.JLabel();
		create1 = new javax.swing.JButton();
		create.setFont(new java.awt.Font("Calibri", 0, 18)); // NOI18N
		create.setText("Create new partition");
		create.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				createActionPerformed(evt);
			}
		});
		tabs.setFont(new java.awt.Font("Calibri", 0, 18));
		jLabel1.setBackground(new java.awt.Color(246, 246, 246));
		jLabel1.setFont(new java.awt.Font("Calibri", 0, 18)); // NOI18N
		jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
		jLabel1.setText("No partition has been created yet");
		jLabel1.setOpaque(true);
		tabs.addTab("tab1", jLabel1);
		create1.setFont(new java.awt.Font("Calibri", 0, 18)); // NOI18N
		create1.setText("close");
		create1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				create1ActionPerformed(evt);
			}
		});
		
		allSlices = new JRadioButton("Show information of all slices");
		allSlices.setFont(new Font("Calibri", Font.PLAIN, 16));
		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
		layout.setHorizontalGroup(
			layout.createParallelGroup(Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
					.addContainerGap()
					.addGroup(layout.createParallelGroup(Alignment.LEADING)
						.addComponent(allSlices)
						.addComponent(tabs, GroupLayout.DEFAULT_SIZE, 454, Short.MAX_VALUE)
						.addGroup(layout.createSequentialGroup()
							.addComponent(create)
							.addGap(18)
							.addComponent(create1)))
					.addContainerGap())
		);
		layout.setVerticalGroup(
			layout.createParallelGroup(Alignment.TRAILING)
				.addGroup(layout.createSequentialGroup()
					.addContainerGap()
					.addComponent(tabs, GroupLayout.PREFERRED_SIZE, 317, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addComponent(allSlices)
					.addPreferredGap(ComponentPlacement.RELATED, 45, Short.MAX_VALUE)
					.addGroup(layout.createParallelGroup(Alignment.BASELINE)
						.addComponent(create)
						.addComponent(create1))
					.addContainerGap())
		);
		getContentPane().setLayout(layout);
	}

	private void createActionPerformed(java.awt.event.ActionEvent evt) {
		previousIterations = 0;
		outputImage = null;
		parameters.setVisible(true);
		setEnabled(false);
	}

	private void create1ActionPerformed(java.awt.event.ActionEvent evt) {
		myDispose();
	}

	private void myDispose() {
		for (Listener l : listenerList) {
			l.removeListeners();
		}
		listenerList.clear();
		parameters.dispose();
		dispose();
	}

	class MyImageListener implements ImageListener {
		Thread t;
		Listener l;

		public MyImageListener(Thread t, Listener l) {
			this.t = t;
			this.l = l;
		}

		public void imageUpdated(ImagePlus arg0) {
		}

		public void imageOpened(ImagePlus arg0) {
		}

		@SuppressWarnings("deprecation")
		public void imageClosed(ImagePlus arg0) {
			if (arg0 == l.output.getImagePlus()) {
				t.stop();
				ImagePlus.removeImageListener(this);
				l.removeListeners();
			}
		}
	};

	public void ParametersOk(final int type, final PixelValue alpha, final PixelValue omega, final float cindex, final int randomPixels, final int iterations) {
		Thread t = new Thread(new Runnable() {
			public void run() {
				setEnabled(true);
				if (tabs.getTabCount() == 1 && tabs.getComponent(0) instanceof JLabel) {
					tabs.removeAll();
				}
				Listener listener = new Listener(img, outputImage, MainFrame.this, type, alpha, omega, cindex, randomPixels, iterations, previousIterations);
				MyImageListener imageListener = new MyImageListener(Thread.currentThread(), listener);
				ImagePlus.addImageListener(imageListener);
				try {
					listener.start();
				} catch (OutOfMemoryError error) {
					NoMemoryFrame wait = new NoMemoryFrame();
					wait.setVisible(true);
					ImagePlus.removeImageListener(imageListener);
					listener.removeListeners();
					if (listener.output != null) {
						listener.output.getImagePlus().close();
					}
					return;
				}
				ImagePlus.removeImageListener(imageListener);
				listenerList.add(listener);
			}
		});
		t.start();
	}

	public void ParametersCancelled() {
		setEnabled(true);
	}
}
